package com.wjc.train.business.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.wjc.train.business.entity.DailyTrain;
import com.wjc.train.business.entity.Train;
import com.wjc.train.business.repository.DailyTrainRepository;
import com.wjc.train.business.repository.TrainRepository;
import com.wjc.train.business.req.DailyTrainQueryReq;
import com.wjc.train.business.req.DailyTrainSaveReq;
import com.wjc.train.business.resp.DailyTrainQueryResp;
import com.wjc.train.business.service.*;
import com.wjc.train.common.enums.LogicEnum;
import com.wjc.train.common.exception.BusinessException;
import com.wjc.train.common.untils.CopyUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 每日车次表 服务实现类
 * </p>
 *
 * @author Guessed
 * @since 2023-08-07
 */
@Service
@Slf4j
public class DailyTrainServiceImpl  implements IDailyTrainService {

    @Resource
    private DailyTrainRepository dailytrainRepository;

    @Resource
    private TrainRepository trainRepository;

    @Resource
    private IDailyTrainStationService dailyTrainStationService;

    @Resource
    private IDailyTrainCarriageService dailytraincarriageService;

    @Resource
    private IDailyTrainSeatService dailyTrainSeatService;

    @Resource
    private IDailyTrainTicketService dailyTrainTicketService;

    @Resource
    private ISkTokenService skTokenService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(DailyTrainSaveReq dailytrainSaveReq) {
        DailyTrain dailytrain = CopyUtil.copy(dailytrainSaveReq, DailyTrain.class);
        dailytrainRepository.saveOrUpdate(dailytrain);
    }

    @Override
    public IPage<DailyTrainQueryResp> queryList(IPage<DailyTrainQueryResp> page, DailyTrainQueryReq dailytrainQueryReq) {
        return dailytrainRepository.queryList(page,dailytrainQueryReq);
    }

    @Override
    public void delete(Long id) {
        dailytrainRepository.getBaseMapper().deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void genDaily(Date date) {
        //查询车次信息
        List<Train> trainList = trainRepository.lambdaQuery()
                .eq(Train::getIsDeleted, LogicEnum.NOT_DELETED.getCode())
                .list();
        if(CollectionUtil.isEmpty(trainList)){
           log.error("不存在车次信息,任务结束");
            throw new BusinessException("不存在车次信息");
        }
        //循环车次，生成当前日期的数据
        trainList.forEach(x->{
            genDailyTrain(date, x);
        });

    }

    private void genDailyTrain(Date date, Train train) {
        log.info("开始生成日期:{},车次:{}的信息", DateUtil.formatDate(date),train.getCode());
        //查询是否存在已有的数据，若存在则删除
        List<DailyTrain> dailyTrainList = dailytrainRepository.lambdaQuery()
                .eq(DailyTrain::getDate, date)
                .eq(DailyTrain::getCode, train.getCode())
                .eq(DailyTrain::getIsDeleted, LogicEnum.NOT_DELETED.getCode()).list();
        if(CollectionUtil.isNotEmpty(dailyTrainList)){
            List<Long> collect = dailyTrainList.stream().map(DailyTrain::getId).collect(Collectors.toList());
            dailytrainRepository.getBaseMapper().deleteBatchIds(collect);
        }
        //生成当前日期数据
        DailyTrain dailyTrain = CopyUtil.copy(train, DailyTrain.class);
        dailyTrain.setId(null);
        dailyTrain.setDate(date);
        dailytrainRepository.save(dailyTrain);

        //生成每日车站信息
        dailyTrainStationService.genDaily(date,train.getCode());
        //生成每日车厢信息
        dailytraincarriageService.genDaily(date,train.getCode());
        //生成每日车座信息
        dailyTrainSeatService.genDaily(date,train.getCode());
        //生成车票信息
        dailyTrainTicketService.genDaily(dailyTrain,date,train.getCode());
        //生成令牌信息
        skTokenService.genDaily(date,train.getCode());
        log.info("结束生成日期:{},车次:{}的信息", DateUtil.formatDate(date),train.getCode());

    }
}
